import {
  _decorator,
  Animation,
  AudioClip,
  CCInteger,
  Collider2D,
  Component,
  Contact2DType,
  EventTouch,
  Input,
  input,
  instantiate,
  Node,
  Prefab,
  Sprite,
  Vec3,
} from "cc";
import { Reward, RewardType } from "./Reward";
import { GameManager } from "./GameManager";
import { LifeCountUI } from "./UI/LifeCountUI";
import { AudioMgr } from "./AudioMgr";
const { ccclass, property } = _decorator;

enum ShootType {
  NONO_SHOOT = 0,
  ONE_SHOOT = 1,
  TWO_SHOOT = 2,
}

@ccclass("Player")
export class Player extends Component {
  @property({ type: Prefab, tooltip: "子弹1预制体" })
  public bullet1: Prefab = null;

  @property({ type: Prefab, tooltip: "子弹2预制体" })
  public bullet2: Prefab = null;

  @property(Node)
  public bulletPosition1: Node = null;

  @property(Node)
  public bulletPosition2: Node = null;

  @property(Node)
  public bulletPosition3: Node = null;

  @property(Node)
  public buttletParent: Node = null;

  @property
  public shootRate: number = 0.5;

  @property({
    type: Animation,
  })
  public animation: Animation = null;

  //   生命值
  @property
  public lifeCount: number = 3;

  @property(LifeCountUI)
  public lifeCountUI: LifeCountUI = null;

  @property(AudioClip)
  public getShootAwardAudio: AudioClip = null;

  @property(AudioClip)
  public getBombAwardAudio: AudioClip = null;

  @property(AudioClip)
  public bulletAudio: AudioClip = null;

  //   子弹发射计时器
  public shootTimer: number = 0;

  public shootType: ShootType = ShootType.ONE_SHOOT;

  // 双发子弹持续时间
  @property
  public twoShootTime: number = 5;

  // 双发子弹计时器
  public twoShootTimer: number = 0;

  public collider: Collider2D = null;

  //   无敌时间
  public invincibleTime: number = 1;
  //   无敌时间计时器
  public invincibleTimer: number = 0;
  //   是否无敌
  public isInvincible: boolean = false;

  public isCanControl: boolean = true;

  protected onLoad(): void {
    input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
  }

  protected onDestroy(): void {
    input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
  }

  start() {
    // 飞机和敌军碰撞检测
    this.collider = this.getComponent(Collider2D);
    if (this.collider) {
      this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
    }
    this.lifeCountUI.onLifeCountChange(this.lifeCount);
  }

  protected update(deltaTime: number) {
    switch (this.shootType) {
      case ShootType.NONO_SHOOT:
        break;
      case ShootType.ONE_SHOOT:
        this.oneShoot(deltaTime);
        break;
      case ShootType.TWO_SHOOT:
        this.twoShoot(deltaTime);
        break;
    }
    this.invincibleTimer += deltaTime;
    if (this.invincibleTimer >= this.invincibleTime) {
      this.isInvincible = false;
    }
  }

  updateLifeCount(count: number) {
    this.lifeCount += count;
    this.lifeCountUI.onLifeCountChange(this.lifeCount);
  }

  /**
   * 单发子弹
   * @param deltaTime
   */
  public oneShoot(deltaTime: number) {
    this.shootTimer += deltaTime;
    if (this.shootTimer >= this.shootRate) {
      this.shootTimer = 0;
      const b1 = instantiate(this.bullet1);
      this.buttletParent.addChild(b1);
      b1.setWorldPosition(this.bulletPosition1.worldPosition);
      AudioMgr.inst.playOneShot(this.bulletAudio, 0.2);
    }
  }

  /**
   * 双发子弹
   * @param deltaTime
   */
  public twoShoot(deltaTime: number) {
    this.twoShootTimer += deltaTime;
    if (this.twoShootTimer >= this.twoShootTime) {
      this.transitionOneShoot();
    }

    this.shootTimer += deltaTime;
    if (this.shootTimer >= this.shootRate) {
      this.shootTimer = 0;
      const b1 = instantiate(this.bullet1);
      const b2 = instantiate(this.bullet2);
      this.buttletParent.addChild(b1);
      this.buttletParent.addChild(b2);
      b1.setWorldPosition(this.bulletPosition2.worldPosition);
      b2.setWorldPosition(this.bulletPosition3.worldPosition);
      AudioMgr.inst.playOneShot(this.bulletAudio, 0.2);
    }
  }

  /**
   * 飞机移动
   * @param event
   */
  onTouchMove(event: EventTouch) {
    if (!this.isCanControl) return;
    if (this.lifeCount <= 0) {
      return;
    }
    const deltaX = event.getDeltaX();
    const deltaY = event.getDeltaY();
    const p = this.node.position;

    const targetPosition = new Vec3(p.x + deltaX, p.y + deltaY, 0);
    if (targetPosition.x < -230) {
      targetPosition.x = -230;
    }

    if (targetPosition.x > 230) {
      targetPosition.x = 230;
    }

    if (targetPosition.y < -380) {
      targetPosition.y = -380;
    }
    if (targetPosition.y > 380) {
      targetPosition.y = 380;
    }
    this.node.setPosition(targetPosition);
  }

  /* 飞机碰撞检测
   * @param selfCollider
   * @param otherCollider
   */
  onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D) {
    const reward = otherCollider.getComponent(Reward);
    if (reward) {
      this.onContactReward(reward);
    } else {
      this.onContactEnemy();
    }
  }

  // 切换双发子弹
  transitionTwoShoot() {
    AudioMgr.inst.playOneShot(this.getShootAwardAudio, 0.2);
    this.shootType = ShootType.TWO_SHOOT;
    this.twoShootTimer = 0;
  }

  // 切换单发子弹
  transitionOneShoot() {
    this.shootType = ShootType.ONE_SHOOT;
    this.twoShootTimer = 0;
  }

  transitionBomb() {
    AudioMgr.inst.playOneShot(this.getBombAwardAudio, 0.2);
    GameManager.instance.addBomb();
  }

  // 解决飞机和奖励多次碰撞导致收集到奖励数量增加的问题
  private lastRewward: Reward = null;

  onContactReward(reward: Reward) {
    if (this.lastRewward == reward) {
      return;
    }
    this.lastRewward = reward;
    switch (reward.rewardType) {
      case RewardType.REWARD_TWOSHOOT:
        this.transitionTwoShoot();
        break;
      case RewardType.REWARD_BOMB:
        this.transitionBomb();
        break;
    }
    // 销毁奖励
    reward.getComponent(Collider2D).enabled = false;
    reward.getComponent(Sprite).enabled = false;
  }
  // 敌机碰撞检测
  onContactEnemy() {
    if (this.isInvincible) {
      return;
    }
    this.isInvincible = true;
    this.invincibleTimer = 0;
    this.updateLifeCount(-1);
    if (this.lifeCount <= 0) {
      this.shootType = ShootType.NONO_SHOOT;
      this.animation.play("Hero_Down");
      if (this.collider) {
        this.collider.enabled = false;
      }
      this.scheduleOnce(() => {
        GameManager.getInstance().gameOver();
      }, 0.4);
    } else {
      this.animation.play("Hero_Hit");
    }
  }

  disabledController() {
    this.isCanControl = false;
  }

  enableController() {
    this.isCanControl = true;
  }
}
